home *** CD-ROM | disk | FTP | other *** search
/ The Business Master (3rd Edition) / The Business Master (3rd Edition).iso / files / utilreen / txt2ps / text2ps.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  9KB  |  381 lines

  1.  
  2. /*
  3.  *    text2ps
  4.  *
  5.  *    Convert plain text to postscript
  6.  *    - Stephen Frede, UNSW, Australia
  7.  */
  8.  
  9. #include    <stdio.h>
  10. #include    <string.h>
  11.  
  12. #define    TRUE        1
  13. #define    FALSE        0
  14. #define    INCH        72.0        /* no. postscript units / inch */
  15. #define    CM        28.35        /* postscript units / cm */
  16. #define NEW_PAGE    014        /* ^L forces a new page */
  17.  
  18. #define    OPAGEOFFSET    (1.0*CM)    /* default hor offset if option used */
  19. #define DTOPMARGIN    (0.5*CM)    /* default top margin */
  20. #define OTOPMARGIN    (1.5*CM)    /* default top margin if option used */
  21. #define    DFONTSIZE    10.0        /* default font size (in points) */
  22. #define    OFONTSIZE    12.0        /* default font size if option used */
  23. #define CHARSPERLINE    10000        /* no. of chars/line */
  24. #define LINESPERPAGE    10000        /* no. of lines/page */
  25. #define    ROTATION    0.0        /* default orientation */
  26. #define    FONT        "Courier"
  27. #define    TABSIZE        8
  28.  
  29.  
  30. /* typedef char    int; */
  31.  
  32. FILE        *ostr;
  33.  
  34. char    usage[] = "Valid text2ps options:\n\t-r[angle]\n\t-f[font]\n\t-s[size]\n\t-h[space]\n\t-p[pitch]\n\t-o[offset]\n\t-oe[offset]\n\t-m[topmargin]\n\t-w[width]\n\t-l[length]\n\t-v\n\t-?\n";
  35. int    tabsize,charsperline,  /* tab spacing in # chars, # chars per line */
  36.     linesperpage;          /* # lines per page */
  37.  
  38. main(argc, argv)
  39. int    argc;
  40. char    **argv;
  41. {
  42.     int    status = 0;    /* exit status (no. errors occured) */
  43.     float    opageoffset,
  44.         epageoffset,
  45.         topmargin,
  46.         fontsize,
  47.         linepitch,
  48.         spacing,
  49.         rotation;
  50.     char    *fontname;
  51.     FILE    *istr;
  52.         double  atof();
  53.  
  54.     fontsize = DFONTSIZE;
  55.     linepitch = 0.0;
  56.     opageoffset = 0.0;
  57.     epageoffset = 0.0;
  58.     topmargin = DTOPMARGIN;
  59.     spacing = 0.0;
  60.     tabsize = TABSIZE;
  61.     charsperline = CHARSPERLINE;
  62.     linesperpage = LINESPERPAGE;
  63.     rotation = ROTATION;
  64.     fontname = FONT;
  65.     ostr = stdout;
  66.     argv++;        /* skip program name */
  67.     while(*argv && **argv == '-')
  68.     {
  69.         char    c;
  70.  
  71.         (*argv)++;    /* skip the '-' */
  72.         c = **argv;    /* option letter */
  73.         (*argv)++;    /* skip option letter */
  74.         switch(c)
  75.         {
  76.             case 'o':    /* offset */
  77.                 if (**argv != 'e') {
  78.                     if(**argv == '\0')
  79.                         opageoffset = OPAGEOFFSET;
  80.                     else
  81.                         opageoffset = atof(*argv) * CM;
  82.                     epageoffset = opageoffset;
  83.                     }
  84.                 else {
  85.                     (*argv)++;
  86.                     if (**argv == '\0')
  87.                         epageoffset = OPAGEOFFSET;
  88.                     else 
  89.                         epageoffset = atof(*argv) * CM;
  90.                     }
  91.                 break;
  92.  
  93.             case 'm':    /* top margin */
  94.                 if(**argv == '\0')
  95.                     topmargin = OTOPMARGIN;
  96.                 else
  97.                     topmargin = atof(*argv) * CM;
  98.                 break;
  99.  
  100.             case 'r':    /* rotation */
  101.                 if(**argv == '\0')
  102.                     rotation = 90.0;
  103.                 else
  104.                     rotation = atof(*argv);
  105.                 break;
  106.  
  107.             case 'p':    /* pitch (line spacing) */
  108.                 linepitch = atof(*argv);
  109.                 break;
  110.  
  111.             case 's':    /* font size */
  112.                 if(**argv == '\0')
  113.                     fontsize = OFONTSIZE;
  114.                 else
  115.                     fontsize = atof(*argv);
  116.                 break;
  117.  
  118.             case 't':    /* tab size */
  119.                 if(**argv == '\0')
  120.                     tabsize = 4;
  121.                 else
  122.                     tabsize = (int) atof(*argv);
  123.                 break;
  124.  
  125.             case 'f':    /* font */
  126.                 if(**argv == '\0')
  127.                     fontname = "Times-Roman";
  128.                 else
  129.                     fontname = *argv;
  130.                 break;
  131.  
  132.             case 'h':    /* horizontal spacing */
  133.                 if(**argv == '\0')
  134.                     spacing = 0.25;
  135.                 else
  136.                     spacing = atof(*argv);
  137.                 break;
  138.  
  139.             case 'w':    /* linewidth (chars per line) */
  140.                 if(**argv == '\0')
  141.                     charsperline = 72;
  142.                 else
  143.                     charsperline = (int) atof(*argv);
  144.                 break;
  145.  
  146.             case 'l':    /* lines per page) */
  147.                 if(**argv == '\0')
  148.                     linesperpage = 60;
  149.                 else
  150.                     linesperpage = (int) atof(*argv);
  151.                 break;
  152.  
  153.             case 'v':    /* version # */
  154.                 fprintf(stderr,"Version 1.04\n");
  155.                 exit(status);
  156.                 break;
  157.  
  158.             case '?':    /* usage - options */
  159.                 fprintf(stderr, usage);
  160.                 exit(status);
  161.                 break;
  162.  
  163.             default:
  164.                         (*argv)--; (*argv)--;
  165.                 fprintf(stderr, "Illegal option: [%s]\n",
  166.                     *argv);
  167.                         (*argv)++; (*argv)++;
  168.                 status++;
  169.                 break;
  170.         }
  171.         argv++;
  172.     }
  173.     if(status)
  174.     {
  175.         fprintf(stderr, usage);
  176.         exit(status);
  177.         /* NOTREACHED */
  178.     }
  179.     if(linepitch == 0)
  180.         linepitch = fontsize + 2;
  181.     spacing *= fontsize;
  182.     init(fontsize, opageoffset, epageoffset, topmargin, linepitch, rotation, fontname, spacing);
  183.     if(! *argv)
  184.         process(stdin);
  185.     else while(*argv)
  186.     {
  187.         if((istr = fopen(*argv, "r")) == NULL)
  188.         {
  189.             perror(*argv);
  190.             status++;
  191.         }
  192.         else
  193.         {
  194.             process(istr);
  195.             fclose(istr);
  196.         }
  197.         argv++;
  198.     }
  199.     putc('\004', ostr);
  200.     exit(status);
  201. }
  202.  
  203. process(istr)
  204. FILE    *istr;
  205. {
  206.     register char    ch;
  207.     register int    x,    /* used for tab calculations and folding */
  208.              linenum;
  209.  
  210.         linenum = 1;
  211.     x = 0;
  212.     putc('(', ostr);
  213.     while((ch=getc(istr)) != EOF)
  214.     {
  215.         if(ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r' && ch != NEW_PAGE)
  216.         {
  217.             ch = '?';
  218.         }
  219.         if(ch == '\t')
  220.         {
  221.             int    n = x + tabsize - (x % tabsize);
  222.  
  223.             while(x < n) {
  224.                     pch(' ');
  225.                     x++;
  226.                 }
  227.         }
  228.         else if(ch == '\n')
  229.         {
  230.             fprintf(ostr, ") n\n");
  231.             linenum = linenum + 1;
  232.             if (linenum > linesperpage) {
  233.                 fprintf(ostr,"p\n");
  234.                 linenum = 1;
  235.             }
  236.             x = 0;
  237.             putc('(', ostr);
  238.         }
  239.         else if(ch == '\r')
  240.         {
  241.             fprintf(ostr, ") r\n");
  242.             x = 0;
  243.             putc('(', ostr);
  244.         }
  245.         else if(ch == NEW_PAGE)
  246.         {
  247.             fprintf(ostr, ") n p\n");
  248.             linenum = 1;
  249.             x = 0;
  250.             putc('(', ostr);
  251.         }
  252.         else
  253.         {
  254.             if (x >= charsperline) {
  255.                 fprintf(ostr, ") n\n");
  256.                 linenum = linenum + 1;
  257.                 if (linenum > linesperpage) {
  258.                     fprintf(ostr,"p\n");
  259.                     linenum = 1;
  260.                 }
  261.                 x = 0;
  262.                 putc('(', ostr);
  263.             }
  264.             pch(ch);
  265.             x++;
  266.         }
  267.     }
  268.     fprintf(ostr, ") n p\n\f");
  269. }
  270.  
  271. char    *inittab[] = {
  272.     /* print a page and start a new one */
  273.     "/p",
  274.     "{ 0.0 coffset sub 0 translate",
  275.         "  /temp coffset def",
  276.         "  /coffset noffset def",
  277.     "  /noffset temp def",
  278.     "  coffset 0 translate",
  279.     "  copypage erasepage newpath 0 pgtop moveto",
  280.     "} def",
  281.     "/n",
  282.     /* show the string given as an arg */
  283.     "{ spacing 0 3 -1 roll ashow",
  284.     /* now move down a line; linepitch is -'ve */
  285.     "  0 linepitch rmoveto",
  286.     /* save the new y posn */
  287.     "  /y currentpoint exch pop def",
  288.     /* test if the next line would be below the bottom margin */
  289.     "  y 0 lt",
  290.     /* if so, print the page, and move to the top of a new page */
  291.     "  { p }",
  292.     /* else go to where the next line is due to start */
  293.     "  { 0 y moveto } ifelse",
  294.     "} def",
  295.     "/r",
  296.     /* show the string given as an arg */
  297.     "{ spacing 0 3 -1 roll ashow",
  298.     /* save y */
  299.     "  /y currentpoint exch pop def",
  300.     /* and then move to the beginning of the current line */
  301.     "  0 y moveto",
  302.     "} def",
  303.     (char *)0 };
  304.  
  305. init(fontsize, opageoffset, epageoffset, topmargin, linepitch, rotation, fontname, spacing)
  306. float    fontsize,
  307.     opageoffset,
  308.     epageoffset,
  309.     topmargin,
  310.     linepitch,
  311.     spacing,
  312.     rotation;
  313. char    *fontname;
  314. {
  315.     register char    **p;
  316.  
  317.     fprintf(ostr, "\004\n");
  318.     p = inittab;
  319.     while(*p)
  320.         fprintf(ostr, "%s\n", *p++);
  321.     fprintf(ostr, "/%s findfont %.1f scalefont setfont\n",
  322.         fontname, fontsize);
  323.     fprintf(ostr, "/linepitch %.1f def\n", -linepitch);
  324.     fprintf(ostr, "/spacing %.1f def\n", spacing);
  325.     fprintf(ostr, "/coffset %.1f def\n", opageoffset + 4);
  326.     fprintf(ostr, "/noffset %.1f def\n", epageoffset + 4);
  327.     /* apply rotation transformation, if any */
  328.     if(rotation != 0.0)
  329.         fprintf(ostr, "%.1f rotate\n", rotation);
  330.     /* get current imageable area */
  331.     fprintf(ostr, "clippath pathbbox\n");
  332.     /* save the upper right y coordinate */
  333.     fprintf(ostr, "/pgtop exch def\n");
  334.     /* save lower left y; translate origin to lower left */
  335.     fprintf(ostr, "pop /y exch def y translate\n");
  336.     /* subtract old lower left from upper right to get top of page */
  337.     /* then subtract top margin to set top of page */
  338.     fprintf(ostr, "/pgtop pgtop y sub %.1f sub linepitch add def\n", topmargin);
  339.     /* apply horizontal offset, if any */
  340.     /* unfortunately, a slight fudge factor is required here */
  341.     fprintf(ostr, "coffset 0 translate\n");
  342.     /* move to top of page, ready to start printing */
  343.     fprintf(ostr, "newpath 0 pgtop moveto\n");
  344. }
  345.  
  346. pch(ch)
  347. int    ch;
  348. {
  349.     if(ch < ' ' || ch > '~')
  350.         fprintf(ostr, "\\%3.3o", ch);
  351.     else
  352.     {
  353.         if(ch == '(' || ch == ')' || ch == '\\')
  354.             putc('\\', ostr);
  355.         putc(ch, ostr);
  356.     }
  357. }
  358.  
  359. double atof(s) /* convert string to double */
  360. char s[];
  361. {
  362.      double val, power;
  363.      int i;
  364.  
  365.      for (i=0; s[i]==' ' || s[i]=='\t'; i++) ;  /* skip white space or tabs */
  366.      if (s[i] == '+' || s[i] == '-')            /* sign -if '-', ignore it */
  367.          i++;
  368.      for (val = 0; s[i] >= '0' && s[i] <= '9'; i++)
  369.           val = 10 * val + s[i] - '0';
  370.      if (s[i] == '.') {
  371.          i++;
  372.          for (power = 1; s[i] >= '0' && s[i] <= '9'; i++) {
  373.               power = power /10;
  374.               val =  power * (s[i] - '0') + val;
  375.          }
  376.      }
  377.      return (val);
  378. }
  379.  
  380.  
  381.